home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NOVA - For the NeXT Workstation
/
NOVA - For the NeXT Workstation.iso
/
SourceCode
/
InspectorManager
/
InspectorManager.m
< prev
next >
Wrap
Text File
|
1992-12-19
|
11KB
|
370 lines
// InspectorManager.m
// By Kevin Brain
// A class for managing an inspector.
// Compositing techniques and functions from the ToolInspector example
// by Sharon Biocca Zakhour, NeXT Developer Support Team
// You may freely copy, distribute and reuse the code in this example.
// *Everybody involved* disclaims any warranty of any kind, expressed
// or implied, as to its fitness for any particular use.
#import <objc/NXStringTable.h>
#import <appkit/Panel.h>
#import <appkit/View.h>
#import <appkit/PopUpList.h>
#import <appkit/Matrix.h>
#import <objc/Storage.h>
#import <objc/List.h>
#import <appkit/Application.h> // for NXApp
#import <dpsclient/wraps.h> // PScomposite
#import <libc.h>
#import "InspectorManager.h"
#define INTERVIEWSPACING 2
@implementation InspectorManager
/* Private functions */
static void
compositeToBuffer(InspectorManager *self, float srcX, float srcY, float width,
float height, float dstX, float dstY)
{
[[self->layouts contentView] lockFocus];
PScomposite(srcX, srcY, width, height,
[[self->inspectorPanel contentView] gState], dstX, dstY, NX_COPY);
[[self->layouts contentView] unlockFocus];
}
static void
compositeToScreen(InspectorManager *self, float srcX, float srcY, float width,
float height, float dstX, float dstY)
{
[[self->inspectorPanel contentView] lockFocus];
PScomposite(srcX, srcY, width, height,
[[self->layouts contentView] gState], dstX, dstY, NX_COPY);
[self->inspectorPanel flushWindow];
[[self->inspectorPanel contentView] unlockFocus];
}
/* instance methods */
- init
{
[super init];
if ([NXApp loadNibSection:"Inspector.nib" owner:self] == nil)
NXRunAlertPanel(NULL,"Couldn't load Inspector.nib","OK",NULL,NULL);
/* Tell the Inspector & Palette panels not to become the key window */
[inspectorPanel setBecomeKeyOnlyIfNeeded: YES]; /* This will only */
/* work if you don't miniaturize the panel. */
[inspectorPanel setFloatingPanel:(BOOL)YES];
useKeyEquivalents = YES;
inspectorList = [[Storage alloc] initCount:0 elementSize:sizeof(struct inspectorListEntry) description:"@*"];
groupList = [[Storage alloc] initCount:0 elementSize:sizeof(struct inspectorListEntry) description:"@*"];
visibleInspectors = [[Storage alloc] initCount:0 elementSize:sizeof(unsigned int) description:"i"];
[revertOKOut removeFromSuperview];
[popupOut removeFromSuperview];
[inspectorPanel display]; // to actually remove the controls
/* 'layouts' is created in IB as the window containing all the */
/* default inspectors side by side. */
/* This window is non-deferred and always kept off-screen */
[[[layouts contentView] allocateGState] lockFocus]; /* The lockFocus forces the */
[[layouts contentView] unlockFocus]; /* gState to become defined */
[[inspectorPanel contentView] allocateGState];
[self addInspector: noInspectorBox
title:[inspectorStrings valueForStringKey: "NoSelectionInspector"]];
[self addInspector: multiInspectorBox
title:[inspectorStrings valueForStringKey: "MultiSelectionInspector"]];
[self addInspector: unapplicableInspectorBox
title:[inspectorStrings valueForStringKey: "UnapplicableInspector"]];
/* Initialize the Inspector to the "Unapplicable Inspector" state */
[self switchToInspector:(unsigned int)NOTAPPLICABLE];
return self;
}
- (unsigned int)addInspector:(id)theView title:(const char *)theTitle
{
return [self addInspector:theView title:theTitle atLocation:LOWERLEFTX :LOWERLEFTY];
}
- (unsigned int)addInspector:(id)theView title:(const char *)theTitle atLocation:(NXCoord)xLoc :(NXCoord)yLoc
{
struct inspectorListEntry tempInspectorEntry;
NXRect theViewRect, cvRect;
tempInspectorEntry.view = theView;
tempInspectorEntry.showing = NO;
tempInspectorEntry.title = malloc(sizeof(char)*(strlen((char *)theTitle)));
strcpy(tempInspectorEntry.title,theTitle);
[theView getFrame:&theViewRect];
[[layouts contentView] getFrame:&cvRect];
[[layouts contentView] addSubview:theView];
if ((lastRect.origin.y+lastRect.size.height+ theViewRect.size.height+INTERVIEWSPACING) >= cvRect.size.height) {
[layouts sizeWindow:(NXCoord)(cvRect.size.width + theViewRect.size.width + INTERVIEWSPACING)
:(NXCoord)cvRect.size.height];
lastRect.origin.x = cvRect.size.width;
lastRect.origin.y = 0;
}
else {
if ((lastRect.origin.x + theViewRect.size.width + INTERVIEWSPACING) >= cvRect.size.width)
[layouts sizeWindow:(NXCoord)(lastRect.origin.x + theViewRect.size.width + INTERVIEWSPACING)
:(NXCoord)cvRect.size.height];
lastRect.origin.y = lastRect.origin.y + lastRect.size.height + INTERVIEWSPACING;
}
lastRect.size = theViewRect.size;
[theView moveTo:lastRect.origin.x :lastRect.origin.y];
[theView display];
[theView getFrame:&tempInspectorEntry.offscreenRect];
[inspectorList addElement:&tempInspectorEntry];
[theView moveTo:xLoc :yLoc];
[theView removeFromSuperview];
return [inspectorList count]-1;
}
- (unsigned int)addGroup:(const char *)theTitle
{
struct inspectorListEntry tempGroupEntry;
unsigned short temp;
// add item to PopUpList
if (([groupList count] < 9) && (useKeyEquivalents == YES)) // command-key equivalents for first 9
temp = (unsigned short)[groupList count]+(unsigned short)'1';
else
temp = 0; // no command-key equivalent for rest
tempGroupEntry.view = [[popupOut target] addItem:theTitle
action:@selector(selectGroup:)
keyEquivalent:temp];
[tempGroupEntry.view setTarget:self];
if ([groupList count] == 0) {
// remove the default 'None' item in PopUpList
[[popupOut target] removeItemAt:(unsigned int)0];
[popupOut setTitle:theTitle];
}
if ([groupList count] == 1)
[self showGroupPopUp];
tempGroupEntry.title = malloc(sizeof(char)*(strlen((char *)theTitle)));
strcpy(tempGroupEntry.title,theTitle);
[groupList addElement:&tempGroupEntry];
return [groupList count]-1;
}
- setUseKeyEquivalents:(BOOL)use
{
useKeyEquivalents = use;
return self;
}
- switchToInspector:(unsigned int)newInspector
{
struct inspectorListEntry *new,*tempOld;
View *tempView;
NXRect tempFrame;
int i,*tempShowing;
unsigned cnt = [visibleInspectors count];
new = [inspectorList elementAt:newInspector];
if (!new) return self; // not a valid inspector
if (new->showing == YES) return self; // if already showing
/* remove all other inspectors */
if (cnt)
for (i=(int)cnt; i > 0;i--) {
tempShowing = [visibleInspectors elementAt:i-1];
tempOld = [inspectorList elementAt:(unsigned int)*tempShowing];
tempOld->showing = NO;
tempView = tempOld->view;
if (tempView != NULL) {
[tempView getFrame:&tempFrame];
compositeToBuffer(self, tempFrame.origin.x, tempFrame.origin.y, NX_WIDTH(&tempFrame),
NX_HEIGHT(&tempFrame), tempOld->offscreenRect.origin.x, tempOld->offscreenRect.origin.y);
[tempView removeFromSuperview];
}
}
[visibleInspectors empty];
[[inspectorPanel contentView] addSubview:new->view];
/* Now composite the new tool view from the offscreen window into the */
/* toolInspector */
[new->view getFrame:&tempFrame];
compositeToScreen(self, new->offscreenRect.origin.x, new->offscreenRect.origin.y,
NX_WIDTH(&tempFrame), NX_HEIGHT(&tempFrame), tempFrame.origin.x, tempFrame.origin.y);
[inspectorPanel setTitle:new->title];
new->showing = YES;
i=(int)newInspector;
[visibleInspectors addElement:&i];
return self;
}
- showInspector:(unsigned int)newInspector
{
struct inspectorListEntry *new;
NXRect tempFrame;
int tempNum;
new = [inspectorList elementAt:newInspector];
if (!new) return self; // not a valid inspector
if ([self showing:newInspector] == YES) return self; // if already showing
[inspectorPanel disableFlushWindow];
[[inspectorPanel contentView] addSubview:new->view];
/* Now composite the new tool view from the offscreen window into the */
/* toolInspector */
[new->view getFrame:&tempFrame];
compositeToScreen(self, new->offscreenRect.origin.x, new->offscreenRect.origin.y,
NX_WIDTH(&tempFrame), NX_HEIGHT(&tempFrame), tempFrame.origin.x, tempFrame.origin.y);
[inspectorPanel setTitle:new->title];
[inspectorPanel reenableFlushWindow];
[inspectorPanel flushWindowIfNeeded];
new->showing = YES;
tempNum = (int)newInspector;
[visibleInspectors addElement:&tempNum];
return self;
}
- hideInspector:(unsigned int)inspectorNum
{
struct inspectorListEntry *new;
View *tempView;
NXRect tempFrame;
int i,cnt = [visibleInspectors count],*tempNum;
new = [inspectorList elementAt:inspectorNum];
if (!new) return self; // not a valid inspector
if(cnt) // find inspectorNum is visibleInspectors list
for (i=cnt; i > 0;i--) {
tempNum = [visibleInspectors elementAt:i-1];
if (inspectorNum == (unsigned)*tempNum) {
[visibleInspectors removeAt:(unsigned)i-1];
new->showing = NO;
tempView = new->view;
if (tempView != NULL) {
[tempView getFrame:&tempFrame];
compositeToBuffer(self, tempFrame.origin.x, tempFrame.origin.y, NX_WIDTH(&tempFrame),
NX_HEIGHT(&tempFrame), new->offscreenRect.origin.x, new->offscreenRect.origin.y);
[tempView removeFromSuperview];
}
}
}
return self;
}
- (BOOL)showing:(unsigned int)inspectorNum
{
struct inspectorListEntry *new;
if (inspectorNum >= [inspectorList count]) return NO; // not a valid inspector
else new = [inspectorList elementAt:(unsigned)inspectorNum];
if (new->showing == YES) return YES;
else return NO;
}
- (int)group
{
// check if a group is selected (none is initially)
if ([[popupOut target] selectedItem] == NULL)
return 0; // if no group selected, return default group (first group added)
else
return [[popupOut target] indexOfItem:[[popupOut target] selectedItem]];
}
- panel
{
return inspectorPanel;
}
- popUpListButton
{
return popupOut;
}
- revertOKMatrix
{
return revertOKOut;
}
- setDelegate:(id)anObject
{
delegate = anObject;
return self;
}
- delegate
{
return delegate;
}
- selectGroup:sender
// target of inspector panel group selector PopUpList
{
[popupOut setTitle:[[sender selectedCell] title]];
[inspectorPanel orderFront:self];
if ([delegate respondsTo:@selector(groupChanged:to:)])
{
[delegate groupChanged:self to:[sender selectedRow]];
}
return self;
}
- revertPressed:sender
// target of inspector panel Revert button
{
if ([delegate respondsTo:@selector(inspectRevert)])
{
[delegate inspectRevert:self];
}
return self;
}
- okPressed:sender
// target of inspector panel OK button
{
if ([delegate respondsTo:@selector(inspectOK)])
{
[delegate inspectOK:self];
}
return self;
}
- showRevertOK
{
[[inspectorPanel contentView] addSubview:revertOKOut];
[revertOKOut display];
return self;
}
- hideRevertOK
{
[revertOKOut removeFromSuperview];
// uncomment the following line to have the Revert/OK buttons
// automatically removed by displaying the contentView
// [[inspectorPanel contentView] display];
return self;
}
- showGroupPopUp
{
[[inspectorPanel contentView] addSubview:popupOut];
[popupOut display];
return self;
}
- hideGroupPopUp
{
[popupOut removeFromSuperview];
[[inspectorPanel contentView] display];
return self;
}
@end